/*
* // +-------------------------------------------------------------------------------------------------
* // |                 有你就好 [ 有节骨乃坚，无心品自端 ]     <http://encoding.wang>
* // +-------------------------------------------------------------------------------------------------
* // |                             独在异乡为异客         每逢佳节倍思亲
* // +-------------------------------------------------------------------------------------------------
* // |                 联系:   <707069100@qq.com>      <http://weibo.com/513778937>
* // +-------------------------------------------------------------------------------------------------
*/

// -----------------------------------------------------------------------------------------------------
// +----------------------------------------------------------------------------------------------------
// |                   ErYang出品 属于小极品          共同学习    共同进步
// +----------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------


package wang.encoding.mroot.admin.common.listener

import org.quartz.CronExpression
import org.quartz.CronTrigger
import org.quartz.Scheduler
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Configuration
import wang.encoding.mroot.admin.common.constant.ConfigConst
import wang.encoding.mroot.admin.common.constant.ResourceConst
import wang.encoding.mroot.admin.common.quartz.QuartzScheduleUtil
import wang.encoding.mroot.admin.common.task.ControllerAsyncTask
import wang.encoding.mroot.admin.common.util.SharedObjectUtil
import wang.encoding.mroot.common.business.Profile
import wang.encoding.mroot.model.entity.system.ScheduleJob
import wang.encoding.mroot.model.enums.StatusEnum
import wang.encoding.mroot.service.system.ScheduleJobService
import java.util.*
import javax.servlet.ServletContext
import javax.servlet.ServletContextEvent
import javax.servlet.ServletContextListener


/**
 * 系统监听器
 *
 * @author ErYang
 */
@Configuration
class SystemConfigListener : ServletContextListener {


    companion object {
        /**
         * logger
         */
        private val logger = LoggerFactory.getLogger(SystemConfigListener::class.java)
    }

    @Value("\${server.servlet.contextPath}")
    private val contextPath: String? = null

    @Value("\${server.port}")
    private val serverPort: String? = null

    @Autowired
    private lateinit var configProperties: ConfigConst

    @Autowired
    private lateinit var resourceProperties: ResourceConst

    @Autowired
    private lateinit var profile: Profile

    @Autowired
    private lateinit var sharedObjectUtil: SharedObjectUtil

    @Autowired
    private lateinit var controllerAsyncTask: ControllerAsyncTask

    @Autowired
    private lateinit var scheduleJobService: ScheduleJobService

    @Autowired
    private lateinit var scheduler: Scheduler

    // -------------------------------------------------------------------------------------------------

    /**
     * 服务器启动初始化
     *
     * @param servletContextEvent ServletContextEvent
     */
    override fun contextInitialized(servletContextEvent: ServletContextEvent) {
        if (logger.isInfoEnabled) {
            logger.info(">>>>>>>>ServletContext启动监听器<<<<<<<<")
        }
        val servletContext: ServletContext = servletContextEvent.servletContext

        // 环境
        val activeProfile: String = profile.getActiveProfile()
        if (logger.isInfoEnabled) {
            logger.info(">>>>>>>>设置PROFILE[$activeProfile]<<<<<<<<")
        }
        servletContext.setAttribute(configProperties.profileName, activeProfile)

        if (logger.isInfoEnabled) {
            logger.info(">>>>>>>>CONTEXT_PATH[${contextPath!!}]<<<<<<<<")
        }
        if (null != contextPath && contextPath.isNotBlank()) {
            if (logger.isInfoEnabled) {
                logger.info(">>>>>>>>设置CONTEXT_PATH[$contextPath]<<<<<<<<")
            }
            val webPath: String = contextPath
            servletContext.setAttribute(configProperties.contextPathName, webPath)
        }
        if (null != serverPort && serverPort.isNotBlank()) {
            if (logger.isInfoEnabled) {
                logger.info(">>>>>>>>设置SERVER_PORT[$serverPort]<<<<<<<<")
            }
            servletContext.setAttribute(configProperties.serverPortName, serverPort)
        }
        val map: Map<String, String> = initResourceMap()
        if (logger.isInfoEnabled) {
            logger.info(">>>>>>>>设置资源信息集合[key=${resourceProperties.mapName},map.size=${map.size}]<<<<<<<<")
        }
        servletContext.setAttribute(resourceProperties.mapName, map)
        // 页面使用的全局变量
        sharedObjectUtil.init(servletContext)

        // 系统配置集合
        if (logger.isInfoEnabled) {
            logger.info(">>>>>>>>设置数据库配置信息Global[CONFIG_MAP]<<<<<<<<")
        }
        controllerAsyncTask.reloadConfigMap()


        // 项目启动时 初始化定时器
        this.initScheduleJobs()

    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 服务器销毁
     *
     * @param servletContextEvent ServletContextEvent
     */
    override fun contextDestroyed(servletContextEvent: ServletContextEvent) {
        if (logger.isInfoEnabled) {
            logger.info(">>>>>>>>ServletContext销毁监听器<<<<<<<<")
        }
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 初始化资源Map 供页面使用
     *
     * @return Map
     */
    private fun initResourceMap(): Map<String, String> {
        val map = HashMap<String, String>(10)

        if (!this.devProfile()) {
            // 七牛 CDN
            val webPath = "http://qiniucnd.yuneryu.com/"
            map[resourceProperties.resourceName] = webPath + resourceProperties.resource
            map[resourceProperties.vendorsName] = webPath + resourceProperties.vendors
            map[resourceProperties.defaultName] = webPath + resourceProperties.default
            map[resourceProperties.appName] = webPath + resourceProperties.app
        } else {
            if (null != contextPath && contextPath.isNotBlank()) {
                val webPath: String = contextPath
                map[resourceProperties.resourceName] = webPath + resourceProperties.resource
                map[resourceProperties.vendorsName] = webPath + resourceProperties.vendors
                map[resourceProperties.defaultName] = webPath + resourceProperties.default
                map[resourceProperties.appName] = webPath + resourceProperties.app
            } else {
                val webPath = "/"
                map[resourceProperties.resourceName] = webPath + resourceProperties.resource
                map[resourceProperties.vendorsName] = webPath + resourceProperties.vendors
                map[resourceProperties.defaultName] = webPath + resourceProperties.default
                map[resourceProperties.appName] = webPath + resourceProperties.app
            }
        }
        return map
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 项目启动时 初始化定时器
     */
    private fun initScheduleJobs() {
        val whereMap: Map<String, Any> = mapOf(ScheduleJob.STATUS to StatusEnum.NORMAL.key)
        val scheduleJobList: List<ScheduleJob>? = scheduleJobService.list(whereMap, null)
        scheduleJobList?.stream()?.filter { scheduleJob ->
            CronExpression.isValidExpression(scheduleJob.cronExpression)
                    && StatusEnum.NORMAL.key == scheduleJob.status
        }?.forEach { scheduleJob ->
            var cronTrigger: CronTrigger? = null
            try {
                cronTrigger = QuartzScheduleUtil.getCronTrigger(scheduler)
            } catch (e: Exception) {
                e.printStackTrace()
            }

            // 如果不存在，则创建
            if (null == cronTrigger) {
                try {
                    QuartzScheduleUtil.deleteScheduleJob(scheduler, scheduleJob)
                    QuartzScheduleUtil.addScheduleJob(scheduler, scheduleJob)
                } catch (e: Exception) {
                    if (logger.isErrorEnabled) {
                        logger.info(">>>>>>>>创建定时任务失败$e<<<<<<<<")
                    }
                }
            } else {
                try {
                    QuartzScheduleUtil.editScheduleJob(scheduler, scheduleJob)
                } catch (e: Exception) {
                    e.printStackTrace()
                    if (logger.isErrorEnabled) {
                        logger.info(">>>>>>>>更新定时任务失败$e<<<<<<<<")

                    }
                }

            }
        }
    }

    // -------------------------------------------------------------------------------------------------

    /**
     * 检验是否是开发环境
     *
     * @return  Boolean
     */
    private fun devProfile(): Boolean {
        // 开发环境
        return profile.devProfile()
    }

// -------------------------------------------------------------------------------------------------

}

// -----------------------------------------------------------------------------------------------------

// End SystemConfigListener class

/* End of file SystemConfigListener.kt */
/* Location: ./src/main/kotlin/wang/encoding/mroot/admin/common/listener/SystemConfigListener.kt */

// -----------------------------------------------------------------------------------------------------
// +----------------------------------------------------------------------------------------------------
// |                           ErYang出品 属于小极品  O(∩_∩)O~~   共同学习    共同进步
// +----------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------
